package com.atguigu.guli.service.trade.service.impl;

import com.atguigu.guli.service.base.dto.CourseDto;
import com.atguigu.guli.service.base.dto.MemberDto;
import com.atguigu.guli.service.base.exception.GuliException;
import com.atguigu.guli.service.base.result.R;
import com.atguigu.guli.service.base.result.ResultCodeEnum;
import com.atguigu.guli.service.trade.entity.Order;
import com.atguigu.guli.service.trade.entity.PayLog;
import com.atguigu.guli.service.trade.feign.EduCourseService;
import com.atguigu.guli.service.trade.feign.UcenterMemberService;
import com.atguigu.guli.service.trade.mapper.OrderMapper;
import com.atguigu.guli.service.trade.mapper.PayLogMapper;
import com.atguigu.guli.service.trade.service.OrderService;
import com.atguigu.guli.service.trade.util.OrderNoUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author luosj
 * @since 2021-07-19
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private EduCourseService eduCourseService;

    @Autowired
    private UcenterMemberService ucenterMemberService;

    @Override
    public String saveOrder(String courseId, String memberId) {

        //查询当前用户是否已有当前课程的订单
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", courseId);
        queryWrapper.eq("member_id", memberId);
        Order orderExist = baseMapper.selectOne(queryWrapper);
        if(orderExist != null){
            return orderExist.getId(); //如果订单已存在，则直接返回订单id
        }

        //查询课程信息
        R rCourse = eduCourseService.getCourseDtoById(courseId);
        //(CourseDto)rCourse.getData().get("courseDto") ==> 返回LinkedHashMap无法进行强制类型转换
        ObjectMapper mapper = new ObjectMapper();
        CourseDto courseDto = mapper.convertValue(rCourse.getData().get("courseDto"), CourseDto.class);
        if(courseDto == null){
            throw new GuliException(ResultCodeEnum.REMOTE_CALL_ERROR);
        }

        //查询用户信息
        R rMember = ucenterMemberService.getMemberDtoById(memberId);
        MemberDto memberDto = mapper.convertValue(rMember.getData().get("memberDto"), MemberDto.class);
        if(memberDto == null){
            throw new GuliException(ResultCodeEnum.REMOTE_CALL_ERROR);
        }

        //创建订单
        Order order = new Order();
        order
                .setOrderNo(OrderNoUtils.getOrderNo())
                .setCourseId(courseId)
                .setCourseTitle(courseDto.getTitle())
                .setCourseCover(courseDto.getCover())
                .setTeacherName(courseDto.getTeacherName())
                .setMemberId(memberId)
                .setMobile(memberDto.getMobile())
                .setNickname(memberDto.getNickname())
                .setStatus(0)//未支付
                .setPayType(1);//微信支付
        Long totalFee = courseDto.getPrice().multiply(new BigDecimal(100)).longValue();
        order.setTotalFee(totalFee);//分

        baseMapper.insert(order);
        return order.getId();
    }

    @Override
    public Order getByOrderId(String orderId, String memberId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("id", orderId)
                .eq("member_id", memberId);
        Order order = baseMapper.selectOne(queryWrapper);
        return order;
    }

    @Override
    public Boolean isBuyByCourseId(String courseId, String memberId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("member_id", memberId)
                .eq("course_id", courseId)
                .eq("status", 1);
        Integer count = baseMapper.selectCount(queryWrapper);
        return count.intValue() > 0;
    }

    @Override
    public List<Order> selectByMemberId(String memberId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("gmt_create");
        queryWrapper.eq("member_id", memberId);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public boolean removeById(String orderId, String memberId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("id", orderId)
                .eq("member_id", memberId);
        return this.remove(queryWrapper);
    }

    public Order getOrderByOrderNo(String orderNo) {

        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        return baseMapper.selectOne(queryWrapper);
    }

    @Autowired
    private PayLogMapper payLogMapper;

    @Override
    public void updateOrderStatus(Map<String, String> map) {

        //更新订单状态
        String orderNo = map.get("out_trade_no");
        //Order order = this.getOrderByOrderNo(orderNo);//select
        //order.setStatus(1);//支付成功
        //baseMapper.updateById(order);//update
        //优化：只有一条update sql语句
        baseMapper.updateStatusByOrderNo(orderNo);

        //记录支付日志
        PayLog payLog = new PayLog();
        payLog
                .setOrderNo(orderNo)
                .setPayTime(new Date())
                .setPayType(1)//支付类型
                .setTotalFee(Long.parseLong(map.get("total_fee")))//总金额(分)
                .setTradeState(map.get("result_code"))//支付状态
                .setTransactionId(map.get("transaction_id"))
                .setAttr(new Gson().toJson(map));
        payLogMapper.insert(payLog);

        //更新课程销量
        Order order = this.getOrderByOrderNo(orderNo);
        eduCourseService.updateBuyCountById(order.getCourseId());
    }

    @Override
    public boolean queryPayStatus(String orderNo) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        Order order = baseMapper.selectOne(queryWrapper);
        return order.getStatus() == 1;
    }
}
